package com.woniuxy.monitor.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.monitor.pojo.Monitor;
import com.woniuxy.monitor.service.MonitorService;
import com.woniuxy.monitor.mapper.MonitorMapper;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**
* @author 86159
* @description 针对表【monitor】的数据库操作Service实现
* @createDate 2025-07-14 19:25:21
*/
@Service
public class MonitorServiceImpl extends ServiceImpl<MonitorMapper, Monitor>
    implements MonitorService{
    // 获取所有有效直播流
    public List<Monitor> getAllActiveStreams() {
        return this.lambdaQuery()
                .isNotNull(Monitor::getDeviceAddress)
                .list();
    }

    /**
     * 转发指定直播流（带防盗链绕过）
     * @param id 监控设备ID
     * @return 直播流响应
     */
    public ResponseEntity<StreamingResponseBody> forwardStream(Integer id) {
        Monitor monitor = this.getById(id);
        if (monitor == null || monitor.getDeviceAddress() == null) {
            return ResponseEntity.notFound().build();
        }

        String deviceAddress = monitor.getDeviceAddress();
        
        return ResponseEntity.ok()
                .header("Content-Type", getContentType(deviceAddress))
                .header("Access-Control-Allow-Origin", "*")
                .body(outputStream -> {
                    try (CloseableHttpClient httpClient = createHttpClientWithFakeHeaders(deviceAddress);
                         CloseableHttpResponse response = httpClient.execute(
                                 new HttpGet(deviceAddress));
                         InputStream inputStream = response.getEntity().getContent()) {

                        byte[] buffer = new byte[4096]; // 增加缓冲区大小，提高传输效率
                        int bytesRead;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                            outputStream.flush(); // 确保数据及时发送
                        }
                    }
                });
    }

    /**
     * 创建带有伪造头信息的HttpClient，用于绕过防盗链
     * @param url 直播流URL，用于判断是哪个平台
     * @return 配置好的HttpClient
     */
    private CloseableHttpClient createHttpClientWithFakeHeaders(String url) {
        String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
        
        // 根据URL判断是哪个平台，设置相应的伪造头信息
        if (url.contains("kuaishou") || url.contains("ksyun") || url.contains("ks.com")) {
            // 快手防盗链绕过
            return HttpClients.custom()
                    .setUserAgent(userAgent)
                    .setDefaultHeaders(Arrays.asList(
                            new BasicHeader("Referer", "https://www.kuaishou.com"),
                            new BasicHeader("Origin", "https://live.kuaishou.com"),
                            new BasicHeader("X-Requested-With", "XMLHttpRequest"),
                            new BasicHeader("Cookie", "did=web_d86297e2b82e4d6a8fd31696d22bad23"),
                            new BasicHeader("Accept", "*/*"),
                            new BasicHeader("Accept-Language", "zh-CN,zh;q=0.9"),
                            new BasicHeader("sec-ch-ua", "\"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\""),
                            new BasicHeader("sec-ch-ua-mobile", "?0"),
                            new BasicHeader("Sec-Fetch-Dest", "empty"),
                            new BasicHeader("Sec-Fetch-Mode", "cors"),
                            new BasicHeader("Sec-Fetch-Site", "same-site")
                    ))
                    .build();
        } else if (url.contains("douyin") || url.contains("tiktok") || url.contains("bytedance")) {
            // 抖音防盗链绕过
            return HttpClients.custom()
                    .setUserAgent(userAgent)
                    .setDefaultHeaders(Arrays.asList(
                            new BasicHeader("Referer", "https://www.douyin.com"),
                            new BasicHeader("Origin", "https://live.douyin.com"),
                            new BasicHeader("X-Requested-With", "XMLHttpRequest"),
                            new BasicHeader("Accept", "*/*"),
                            new BasicHeader("Accept-Language", "zh-CN,zh;q=0.9"),
                            new BasicHeader("sec-ch-ua", "\"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\""),
                            new BasicHeader("sec-ch-ua-mobile", "?0"),
                            new BasicHeader("Sec-Fetch-Dest", "empty"),
                            new BasicHeader("Sec-Fetch-Mode", "cors"),
                            new BasicHeader("Sec-Fetch-Site", "same-site")
                    ))
                    .build();
        } else {
            // 通用防盗链绕过
            return HttpClients.custom()
                    .setUserAgent(userAgent)
                    .setDefaultHeaders(Arrays.asList(
                            new BasicHeader("Referer", "https://www.example.com"),
                            new BasicHeader("Origin", "https://www.example.com"),
                            new BasicHeader("X-Requested-With", "XMLHttpRequest"),
                            new BasicHeader("Accept", "*/*"),
                            new BasicHeader("Accept-Language", "zh-CN,zh;q=0.9")
                    ))
                    .build();
        }
    }

    private String getContentType(String url) {
        if (url.contains(".m3u8")) return "application/vnd.apple.mpegurl";
        if (url.contains(".flv")) return "video/x-flv";
        return "application/octet-stream";
    }

}




